Hibernate Inheritance Mapping হল Hibernate ORM এর একটি বৈশিষ্ট্য যা inheritance (উত্তরণ) সম্পর্কিত ধারণাগুলিকে Object-Relational Mapping (ORM)-এর মাধ্যমে ডেটাবেস টেবিলের সাথে সম্পর্কিত করে। এর মাধ্যমে আপনি Java ক্লাসে বিভিন্ন ধরনের inheritance পদ্ধতি ব্যবহার করতে পারেন, যেমন single-table inheritance, joined-table inheritance, এবং table-per-class inheritance। Hibernate ডাটাবেসের সাথে inheritance relationship ম্যাপ করতে সহায়তা করে।
Hibernate Inheritance Mapping আপনাকে একই অ্যাপ্লিকেশনে class hierarchy পরিচালনা করতে সক্ষম করে, যেখানে পেরেন্ট এবং চাইল্ড ক্লাসের ডেটাবেস টেবিলগুলিকে উপযুক্তভাবে ম্যাপ করা হয়।
এখানে Hibernate Inheritance Mapping এর বিভিন্ন স্ট্রাটেজি সম্পর্কে বিস্তারিত আলোচনা করা হয়েছে:
Hibernate-এ তিনটি প্রধান inheritance mapping স্ট্রাটেজি রয়েছে:
এই স্ট্রাটেজিতে সমস্ত ক্লাস (পেরেন্ট এবং চাইল্ড) একটিমাত্র টেবিলে ম্যাপ করা হয়। সমস্ত ক্লাসের জন্য একটি বড় টেবিল তৈরি হয় এবং সেখানে একটি স্পেশাল কলাম থাকে যা discriminator হিসেবে কাজ করে, যাতে Hibernate জানে কোন রেকর্ড কোন ক্লাসের অন্তর্ভুক্ত।
import javax.persistence.Entity;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Id;
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "vehicle_type", discriminatorType = DiscriminatorType.STRING)
public class Vehicle {
@Id
private int id;
private String brand;
// Getter and Setter methods
}
@Entity
public class Car extends Vehicle {
private int doors;
// Getter and Setter methods
}
@Entity
public class Bike extends Vehicle {
private boolean hasCarrier;
// Getter and Setter methods
}
এখানে, Vehicle ক্লাস পেরেন্ট হিসেবে কাজ করছে, এবং Car ও Bike হল চাইল্ড ক্লাস। @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
নির্দেশ করে যে সব ক্লাসের ডেটা এক টেবিলে থাকবে।
এই ক্ষেত্রে, Hibernate একাধিক discriminator column ব্যবহার করে vehicle_type কলামটি নির্ধারণ করবে, যাতে এটি বুঝতে পারে কোন রেকর্ড Car বা Bike ক্লাসের অন্তর্গত।
+----+--------+--------------+------+
| id | brand | vehicle_type | ... |
+----+--------+--------------+------+
| 1 | Toyota | Car | ... |
| 2 | Yamaha | Bike | ... |
+----+--------+--------------+------+
এই স্ট্রাটেজিতে, পেরেন্ট এবং চাইল্ড ক্লাসের জন্য আলাদা টেবিল তৈরি করা হয়, তবে একে অপরের সাথে JOIN করা হয়। পেরেন্ট ক্লাসের টেবিলটি মূলত সমস্ত সাধারণ তথ্য ধারণ করবে এবং চাইল্ড ক্লাসের টেবিলগুলি শুধুমাত্র তাদের নির্দিষ্ট বৈশিষ্ট্য ধারণ করবে।
import javax.persistence.Entity;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Id;
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Vehicle {
@Id
private int id;
private String brand;
// Getter and Setter methods
}
@Entity
public class Car extends Vehicle {
private int doors;
// Getter and Setter methods
}
@Entity
public class Bike extends Vehicle {
private boolean hasCarrier;
// Getter and Setter methods
}
এখানে, Vehicle ক্লাস পেরেন্ট ক্লাস হিসেবে কাজ করছে এবং Car এবং Bike ক্লাস আলাদা টেবিল তৈরি করবে। Hibernate একে অপরের সাথে JOIN করে তথ্য সংগ্রহ করবে।
+----+--------+
| id | brand |
+----+--------+
| 1 | Toyota |
| 2 | Yamaha |
+----+--------+
+----+--------+------+
| id | brand | doors|
+----+--------+------+
| 1 | Toyota | 4 |
+----+--------+------+
+----+--------+------------+
| id | brand | hasCarrier |
+----+--------+------------+
| 2 | Yamaha | true |
+----+--------+------------+
এই স্ট্রাটেজিতে, প্রতিটি ক্লাসের জন্য একটি আলাদা টেবিল তৈরি করা হয় এবং প্রতিটি টেবিলের মধ্যে পেরেন্ট ক্লাসের সকল প্রপার্টি কপি করা হয়। এতে ডেটাবেসের টেবিল গুলো অদ্বিতীয় হয় এবং ডেটা রিড বা রাইট করার জন্য ভিন্ন টেবিল ব্যবহৃত হয়।
import javax.persistence.Entity;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Id;
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Vehicle {
@Id
private int id;
private String brand;
// Getter and Setter methods
}
@Entity
public class Car extends Vehicle {
private int doors;
// Getter and Setter methods
}
@Entity
public class Bike extends Vehicle {
private boolean hasCarrier;
// Getter and Setter methods
}
এখানে, Vehicle, Car, এবং Bike প্রতিটি ক্লাসের জন্য আলাদা টেবিল তৈরি হবে।
+----+--------+
| id | brand |
+----+--------+
| 1 | Toyota |
| 2 | Yamaha |
+----+--------+
+----+--------+------+
| id | brand | doors|
+----+--------+------+
| 1 | Toyota | 4 |
+----+--------+------+
+----+--------+------------+
| id | brand | hasCarrier |
+----+--------+------------+
| 2 | Yamaha | true |
+----+--------+------------+
Hibernate-এ Inheritance Mapping ব্যবহার করার মাধ্যমে আপনি আপনার অ্যাপ্লিকেশনের মধ্যে class hierarchy সঠিকভাবে পরিচালনা করতে পারেন। এটি আপনাকে single-table, joined-table, অথবা table-per-class স্ট্রাটেজি অনুযায়ী ডেটাবেসের টেবিলগুলির মধ্যে সম্পর্ক স্থাপন করতে সহায়তা করে। আপনি আপনার অ্যাপ্লিকেশনের জন্য সবচেয়ে উপযুক্ত স্ট্রাটেজি বেছে নেবেন, যা performance, data redundancy, এবং maintenance এর জন্য সবচেয়ে কার্যকরী হবে।
Hibernate ORM (Object-Relational Mapping) ফ্রেমওয়ার্ক, ডেটাবেসের object-oriented ডেটা মডেল এবং relational database টেবিলের মধ্যে সম্পর্ক স্থাপন করতে ব্যবহৃত হয়। Hibernate Inheritance Mapping একটি অত্যন্ত গুরুত্বপূর্ণ ফিচার যা inheritance relationship (উত্তরাধিকার সম্পর্ক) ম্যানেজ করতে সাহায্য করে, যেখানে এক ক্লাস (superclass) এবং তার উপশ্রেণী (subclasses) এর মধ্যে সম্পর্ক স্থাপন করা হয়।
Hibernate এ Inheritance Mapping ব্যবহৃত হয় যখন Java ক্লাসের মধ্যে ইনহেরিটেন্স (inheritance) ব্যবহার করা হয়, এবং আপনাকে সেগুলোকে ডেটাবেসে ম্যাপ করতে হয়। Hibernate তিনটি মূল inheritance strategies প্রদান করে:
এই স্ট্রাটেজিতে, সমস্ত ইনহেরিটেন্স সম্পর্কিত ক্লাসগুলোর জন্য একটিমাত্র টেবিল ব্যবহার করা হয়। সমস্ত প্রপার্টি (superclass এবং subclass) একটি টেবিলের মধ্যে সংরক্ষিত হয়। @DiscriminatorColumn এবং @DiscriminatorValue অ্যানোটেশনগুলি দিয়ে নির্ধারণ করা হয় কোন ক্লাসের কোন রেকর্ড।
ধরা যাক আমাদের একটি Employee ক্লাস রয়েছে, যা FullTimeEmployee এবং PartTimeEmployee নামে দুটি সাবক্লাস ইনহেরিট করে।
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "employee_type")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
// Getters, Setters, Constructors
}
@Entity
@DiscriminatorValue("FullTime")
public class FullTimeEmployee extends Employee {
private double salary;
// Getters, Setters, Constructors
}
@Entity
@DiscriminatorValue("PartTime")
public class PartTimeEmployee extends Employee {
private double hourlyRate;
// Getters, Setters, Constructors
}
এখানে, @DiscriminatorColumn
এবং @DiscriminatorValue
ব্যবহার করা হয়েছে যাতে FullTimeEmployee এবং PartTimeEmployee ক্লাসগুলো আলাদা করে ডেটাবেসে সংরক্ষিত হয়।
এই স্ট্রাটেজিতে, প্রতিটি ক্লাসের জন্য একটি আলাদা টেবিল তৈরি হয় এবং তাদের মধ্যে একটি join সম্পর্ক থাকে। Superclass টেবিলের মধ্যে সাধারণ প্রপার্টি থাকবে, এবং subclasses তাদের নিজস্ব টেবিলের মধ্যে নির্দিষ্ট প্রপার্টি সংরক্ষণ করবে। এই পদ্ধতিতে normalization উন্নত হয় এবং data redundancy কম থাকে।
ধরা যাক আমাদের আবারও Employee এবং এর দুটি সাবক্লাস FullTimeEmployee এবং PartTimeEmployee আছে।
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
// Getters, Setters, Constructors
}
@Entity
public class FullTimeEmployee extends Employee {
private double salary;
// Getters, Setters, Constructors
}
@Entity
public class PartTimeEmployee extends Employee {
private double hourlyRate;
// Getters, Setters, Constructors
}
এখানে, @Inheritance(strategy = InheritanceType.JOINED)
ব্যবহার করা হয়েছে, যার মাধ্যমে সব ক্লাসের জন্য আলাদা টেবিল তৈরি করা হয় এবং Employee টেবিলটি অন্য টেবিলগুলির সাথে join হয়ে থাকে।
এই স্ট্রাটেজিতে, প্রতিটি ক্লাসের জন্য সম্পূর্ণ একটি আলাদা টেবিল তৈরি হয়। প্রতিটি টেবিল তার নিজস্ব প্রপার্টি এবং ইনহেরিটেড প্রপার্টি সংরক্ষণ করে। কোনো join সম্পর্ক থাকে না এবং একেবারে আলাদা টেবিল ব্যবহৃত হয়।
এখানে, Employee এবং তার সাবক্লাসগুলোর জন্য আলাদা টেবিল তৈরি করা হবে।
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
// Getters, Setters, Constructors
}
@Entity
public class FullTimeEmployee extends Employee {
private double salary;
// Getters, Setters, Constructors
}
@Entity
public class PartTimeEmployee extends Employee {
private double hourlyRate;
// Getters, Setters, Constructors
}
এখানে, @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
ব্যবহার করা হয়েছে, যার মাধ্যমে Employee, FullTimeEmployee, এবং PartTimeEmployee ক্লাসের জন্য আলাদা টেবিল তৈরি হবে।
Hibernate এর Inheritance Mapping তিনটি স্ট্রাটেজি মাধ্যমে ডেটাবেসের সাথে অবজেক্ট ইনহেরিটেন্স সম্পর্ক তৈরি করতে সহায়ক:
প্রতিটি স্ট্রাটেজির নিজস্ব সুবিধা এবং অসুবিধা রয়েছে, এবং আপনি আপনার অ্যাপ্লিকেশনটির প্রয়োজন অনুসারে সবচেয়ে উপযুক্ত স্ট্রাটেজি নির্বাচন করতে পারেন। Single Table স্ট্রাটেজি সাধারণত দ্রুত এবং সহজ, কিন্তু Joined এবং Table per Class স্ট্রাটেজি সাধারণত data normalization এর জন্য ভালো।
Single Table Strategy হল Hibernate ORM-এ Inheritance Mapping পদ্ধতির একটি ধরন, যেখানে সমস্ত অবজেক্টের ডেটা একটি একক টেবিলেই সংরক্ষিত হয়, এবং ইনহেরিটেড ক্লাসের মধ্যে পার্থক্য চিহ্নিত করার জন্য একটি বিশেষ কলাম ব্যবহৃত হয়। এটি Inheritance Mapping এর মধ্যে সবচেয়ে সহজ পদ্ধতি, কারণ এখানে সমস্ত ডেটা একটি মাত্র টেবিলের মধ্যে থাকে এবং পারেন্ট এবং চাইল্ড ক্লাসের সকল ডেটা একই টেবিলে সংরক্ষিত হয়।
Hibernate এর Single Table Strategy-এ:
@DiscriminatorColumn
অ্যানোটেশন দ্বারা চিহ্নিত হয়) থাকে যা নির্ধারণ করে কোন রেকর্ডটি কোন ক্লাসের অন্তর্গত। এই কলামটি type বা class type নির্দেশ করে।ধরা যাক, আমাদের দুটি ক্লাস আছে: Employee
(Parent class) এবং Manager
, Developer
(Child classes)। আমরা Single Table Strategy ব্যবহার করব।
import javax.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "employee_type", discriminatorType = DiscriminatorType.STRING)
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
private String department;
// Getters and Setters
}
@Entity
@DiscriminatorValue("Manager")
public class Manager extends Employee {
private int teamSize;
// Getters and Setters
}
@Entity
@DiscriminatorValue("Developer")
public class Developer extends Employee {
private String programmingLanguage;
// Getters and Setters
}
এখানে:
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
: এটি বলে দেয় যে ইনহেরিটেন্স স্ট্রাটেজি হল Single Table।@DiscriminatorColumn(name = "employee_type", discriminatorType = DiscriminatorType.STRING)
: এটি employee_type
নামের একটি কলাম তৈরি করবে, যা প্রতিটি রেকর্ডের জন্য ক্লাস টাইপ চিহ্নিত করবে (যেমন Manager
বা Developer
)।@DiscriminatorValue("Manager")
এবং @DiscriminatorValue("Developer")
: এগুলি চাইল্ড ক্লাসের জন্য নির্দিষ্ট ডিসক্রিমিনেটর ভ্যালু হিসেবে কাজ করবে।এই কোডের মাধ্যমে Hibernate একটি টেবিল তৈরি করবে, যার নাম হবে Employee
(বা আপনার ক্লাসের নাম অনুযায়ী)। এই টেবিলে সমস্ত Employee
, Manager
, এবং Developer
রেকর্ড থাকবে। প্রতিটি রেকর্ডের জন্য employee_type
কলামটি ব্যবহৃত হবে, যা এই রেকর্ডটির জন্য ডিসক্রিমিনেটর ভ্যালু (যেমন Manager
বা Developer
) ধারণ করবে।
Employee Table Structure:
id | name | department | employee_type | teamSize | programmingLanguage |
---|---|---|---|---|---|
1 | John | HR | Manager | 10 | NULL |
2 | Alice | IT | Developer | NULL | Java |
3 | Bob | Marketing | Manager | 5 | NULL |
4 | Charlie | IT | Developer | NULL | Python |
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class EmployeeExample {
public static void main(String[] args) {
SessionFactory factory = new Configuration()
.configure("hibernate.cfg.xml")
.addAnnotatedClass(Employee.class)
.addAnnotatedClass(Manager.class)
.addAnnotatedClass(Developer.class)
.buildSessionFactory();
Session session = factory.getCurrentSession();
try {
// Create new Manager and Developer objects
Manager manager = new Manager();
manager.setName("John");
manager.setDepartment("HR");
manager.setTeamSize(10);
Developer developer = new Developer();
developer.setName("Alice");
developer.setDepartment("IT");
developer.setProgrammingLanguage("Java");
// Start transaction
session.beginTransaction();
// Save both objects
session.save(manager);
session.save(developer);
// Commit transaction
session.getTransaction().commit();
System.out.println("Saved manager and developer successfully!");
} finally {
factory.close();
}
}
}
SELECT
, UPDATE
, DELETE
) দ্রুত হতে পারে, কারণ JOIN অপারেশন করার প্রয়োজন নেই।Hibernate-এ Single Table Strategy হল একটি ইনহেরিটেন্স ম্যাপিং কৌশল যা Object-Relational Mapping (ORM) সম্পর্কিত ডেটা সহজে সংরক্ষণ এবং পরিচালনা করার জন্য ব্যবহৃত হয়। এটি performance এবং simplicity প্রদান করে, তবে data redundancy এবং scalability issues হতে পারে, বিশেষত বড় ইনহেরিটেন্স স্ট্রাকচার থাকলে।
এই কৌশলটি ছোট এবং মাঝারি ইনহেরিটেন্স কাঠামো যেখানে ডেটার পুনরাবৃত্তি কম এবং খুব বেশি কলাম বাড়ানোর প্রয়োজন নেই, সেখানে খুব উপযোগী।
Hibernate-এ Joined Table Strategy হল Inheritance Mapping এর একটি পদ্ধতি যা আপনি ব্যবহার করতে পারেন যখন আপনার জাভা ক্লাসগুলি একে অপরের সাথে সম্পর্কিত হয় এবং আপনি চান যে ডাটাবেসে পৃথক টেবিলগুলিতে এই সম্পর্কগুলিকে সংরক্ষণ করা হোক। এটি Single Table Strategy এবং Table per Subclass থেকে আলাদা, কারণ এটি ইনহেরিটেড ক্লাসের জন্য পৃথক টেবিল তৈরি করে এবং তাদের মধ্যে একটি join তৈরি করে।
Hibernate-এ Joined Table Strategy হল একটি পদ্ধতি যেখানে superclass এবং subclass ক্লাসগুলির জন্য আলাদা আলাদা টেবিল তৈরি করা হয় এবং তারপরে একটি JOIN ব্যবহার করে তাদের মধ্যে সম্পর্ক স্থাপন করা হয়। এর মাধ্যমে, আপনি আপনার ইনহেরিটেন্স হায়ারার্কি (superclass ও subclass) ডাটাবেসে পৃথক টেবিল হিসেবে সংরক্ষণ করতে পারেন।
@PrimaryKeyJoinColumn
ব্যবহার করে।@Inheritance(strategy = InheritanceType.JOINED)
ব্যবহার করলে Hibernate জানবে যে এটি Joined Table Strategy।যদি আপনার এমন একটি পরিস্থিতি থাকে যেখানে আপনি Inheritance ব্যবহার করছেন এবং আপনার ক্লাসের বিভিন্ন সাবক্লাসগুলির জন্য আলাদা টেবিল প্রয়োজন, তবে Joined Table Strategy কার্যকর হতে পারে। এতে প্রতিটি সাবক্লাসের জন্য পৃথক টেবিল থাকবে এবং সেই টেবিলগুলি মূল টেবিলের সাথে join করা হবে। এটি ডেটা সঞ্চয় করার জন্য আরও নর্মালাইজড একটি কাঠামো সরবরাহ করে।
এখানে, আমরা একটি Employee
ক্লাস এবং তার সাবক্লাস FullTimeEmployee
এবং PartTimeEmployee
তৈরি করব।
Employee
)import javax.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.JOINED) // Specify JOINED inheritance strategy
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
public Employee() {}
public Employee(String name) {
this.name = name;
}
// Getters and setters
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
এখানে, Employee
ক্লাসটি সুপারক্লাস হিসেবে কাজ করছে এবং @Inheritance(strategy = InheritanceType.JOINED)
অ্যানোটেশনটি ব্যবহার করা হয়েছে যাতে Hibernate জানে যে এটি Joined Table Strategy ব্যবহার করবে।
FullTimeEmployee
)import javax.persistence.*;
@Entity
public class FullTimeEmployee extends Employee {
private double salary;
public FullTimeEmployee() {}
public FullTimeEmployee(String name, double salary) {
super(name);
this.salary = salary;
}
// Getters and setters
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
এখানে, FullTimeEmployee
ক্লাসটি Employee
ক্লাস থেকে ইনহেরিট করেছে এবং এর নিজস্ব salary
ফিল্ড রয়েছে।
PartTimeEmployee
)import javax.persistence.*;
@Entity
public class PartTimeEmployee extends Employee {
private int hoursWorked;
public PartTimeEmployee() {}
public PartTimeEmployee(String name, int hoursWorked) {
super(name);
this.hoursWorked = hoursWorked;
}
// Getters and setters
public int getHoursWorked() {
return hoursWorked;
}
public void setHoursWorked(int hoursWorked) {
this.hoursWorked = hoursWorked;
}
}
এখানে, PartTimeEmployee
ক্লাসটি Employee
থেকে ইনহেরিট করেছে এবং এর নিজস্ব hoursWorked
ফিল্ড রয়েছে।
Hibernate কনফিগারেশন ফাইল hibernate.cfg.xml
তৈরি করুন যাতে ডাটাবেস সংযোগের সমস্ত প্রপার্টি এবং টেবিল সম্পর্কিত কনফিগারেশন থাকে।
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- JDBC Database connection settings -->
<property name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property>
<property name="hibernate.connection.driver_class">org.h2.Driver</property>
<property name="hibernate.connection.url">jdbc:h2:mem:test;DB_CLOSE_DELAY=-1</property>
<property name="hibernate.connection.username">sa</property>
<property name="hibernate.connection.password"></property>
<!-- Enable Hibernate's automatic session context management -->
<property name="hibernate.current_session_context_class">thread</property>
<!-- Show SQL -->
<property name="hibernate.show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- Mention the annotated class -->
<mapping class="com.example.hibernate.Employee"/>
<mapping class="com.example.hibernate.FullTimeEmployee"/>
<mapping class="com.example.hibernate.PartTimeEmployee"/>
</session-factory>
</hibernate-configuration>
এখানে, hibernate.cfg.xml
ফাইলে ডাটাবেস সংযোগ এবং Hibernate কনফিগারেশন সম্পর্কিত সমস্ত তথ্য দেওয়া হয়েছে।
এখন, আমরা Session
এবং Transaction
ব্যবহার করে ডেটা সেভ করব। যখন আপনি Joined Table Strategy ব্যবহার করেন, Hibernate দুটি টেবিল তৈরি করবে — একটি Employee
টেবিল এবং অন্যটি FullTimeEmployee
বা PartTimeEmployee
টেবিল।
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
public class MainApp {
public static void main(String[] args) {
// Hibernate configuration and session factory setup
SessionFactory sessionFactory = new org.hibernate.cfg.Configuration()
.configure("hibernate.cfg.xml")
.addAnnotatedClass(Employee.class)
.addAnnotatedClass(FullTimeEmployee.class)
.addAnnotatedClass(PartTimeEmployee.class)
.buildSessionFactory();
// Creating session
Session session = sessionFactory.getCurrentSession();
try {
// Start a transaction
Transaction transaction = session.beginTransaction();
// Create FullTimeEmployee instance
FullTimeEmployee fullTimeEmployee = new FullTimeEmployee("John", 50000);
// Save the object
session.save(fullTimeEmployee);
// Commit the transaction
transaction.commit();
System.out.println("Employee saved successfully!");
} finally {
sessionFactory.close();
}
}
}
এখানে, FullTimeEmployee
অবজেক্ট তৈরি করে সেভ করা হচ্ছে। Hibernate Employee
টেবিলের জন্য একটি রেকর্ড তৈরি করবে এবং FullTimeEmployee
টেবিলের জন্য আলাদা একটি রেকর্ড তৈরি করবে, যেটি Employee
টেবিলের সঙ্গে JOIN হয়ে থাকবে।
Hibernate Joined Table Strategy ব্যবহার করলে ডাটাবেসে দুটি টেবিল তৈরি হবে:
Employee টেবিল (Superclass):
CREATE TABLE Employee (
id INT PRIMARY KEY,
name VARCHAR(255)
);
FullTimeEmployee টেবিল (Subclass):
CREATE TABLE FullTimeEmployee (
id INT PRIMARY KEY,
salary DOUBLE,
FOREIGN KEY (id) REFERENCES Employee(id)
);
JOIN
করতে হতে পারে, যা কিছু পরিমাণে কোড এবং কুয়েরি জটিল করতে পারে।Hibernate-এর Joined Table Strategy ব্যবহার করে আপনি Inheritance Mapping এবং Normalization করতে পারেন, যেখানে আপনার superclass এবং subclass এর জন্য পৃথক টেবিল তৈরি হয় এবং তাদের মধ্যে সম্পর্ক JOIN এর মাধ্যমে স্থাপন করা হয়। এই পদ্ধতি ডেটাবেসের টেবিলগুলিকে আরও মডুলার এবং পরিষ্কারভাবে তৈরি করতে সাহায্য করে, তবে কিছু ক্ষেত্রে JOIN এর কারণে পারফরম্যান্স সমস্যাও হতে পারে।
Hibernate-এ Table per Class Strategy একটি ইনহেরিটেন্স স্ট্রাটেজি যা Single Table Inheritance থেকে ভিন্ন। এই স্ট্রাটেজিতে, প্রতিটি ক্লাস (বিশেষত সুপার ক্লাস এবং সাব ক্লাস) আলাদা আলাদা টেবিল হিসেবে ডাটাবেসে সংরক্ষিত হয়। এটি "Concrete Table Inheritance" নামেও পরিচিত, কারণ সব ক্লাসের জন্য আলাদা টেবিল তৈরি করা হয় এবং তাদের মধ্যে সম্পর্ক সাধারণত Join এর মাধ্যমে স্থাপন করা হয় না।
JOIN
অপারেশনের প্রয়োজন হয় না, কারণ প্রতিটি ক্লাসের জন্য আলাদা টেবিল থাকে।ধরা যাক, আমাদের একটি Employee সুপার ক্লাস রয়েছে এবং এটি দুটি সাব ক্লাস FullTimeEmployee এবং PartTimeEmployee তে ইনহেরিট করা হয়।
Employee
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class Employee {
@Id
private int id;
private String name;
// Getters and Setters
}
FullTimeEmployee
import javax.persistence.Entity;
@Entity
public class FullTimeEmployee extends Employee {
private double salary;
// Getters and Setters
}
PartTimeEmployee
import javax.persistence.Entity;
@Entity
public class PartTimeEmployee extends Employee {
private double hourlyRate;
// Getters and Setters
}
hibernate.cfg.xml
for Table per Class StrategyHibernate এর কনফিগারেশন ফাইলে আপনি @Inheritance
অ্যানোটেশন ব্যবহার করে স্ট্রাটেজি সিলেক্ট করতে পারবেন। আমরা @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
ব্যবহার করব।
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Employee {
@Id
private int id;
private String name;
// Getters and Setters
}
এখানে, @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
নির্দেশনা দিয়ে Hibernate জানায় যে প্রতিটি ক্লাসের জন্য আলাদা টেবিল তৈরি করতে হবে।
এখন Hibernate এই Employee, FullTimeEmployee, এবং PartTimeEmployee ক্লাসের জন্য আলাদা টেবিল তৈরি করবে। টেবিলগুলির সিএলএল দেখতে কিছুটা এইরকম হবে:
CREATE TABLE Employee (
id INT PRIMARY KEY,
name VARCHAR(255)
);
CREATE TABLE FullTimeEmployee (
id INT PRIMARY KEY,
name VARCHAR(255),
salary DOUBLE
);
CREATE TABLE PartTimeEmployee (
id INT PRIMARY KEY,
name VARCHAR(255),
hourlyRate DOUBLE
);
এখন আপনি এই টেবিলগুলো ব্যবহার করে ডেটা ইনসার্ট করতে পারেন, যেখানে প্রতিটি ক্লাসের জন্য আলাদা টেবিল থাকবে।
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class EmployeeTest {
public static void main(String[] args) {
SessionFactory factory = new Configuration().configure("hibernate.cfg.xml")
.addAnnotatedClass(FullTimeEmployee.class)
.addAnnotatedClass(PartTimeEmployee.class)
.buildSessionFactory();
Session session = factory.getCurrentSession();
try {
// Create Employee objects
FullTimeEmployee fullTimeEmployee = new FullTimeEmployee();
fullTimeEmployee.setName("John Doe");
fullTimeEmployee.setSalary(50000);
PartTimeEmployee partTimeEmployee = new PartTimeEmployee();
partTimeEmployee.setName("Jane Smith");
partTimeEmployee.setHourlyRate(20);
// Start a transaction
session.beginTransaction();
// Save the employees
session.save(fullTimeEmployee);
session.save(partTimeEmployee);
// Commit transaction
session.getTransaction().commit();
} finally {
factory.close();
}
}
}
এখন যখন আপনি ডেটা রিট্রিভ করবেন, Hibernate বিভিন্ন টেবিল থেকে ডেটা একত্রিত করবে এবং সেগুলিকে অবজেক্টে ম্যাপ করবে। উদাহরণস্বরূপ:
public class EmployeeTest {
public static void main(String[] args) {
SessionFactory factory = new Configuration().configure("hibernate.cfg.xml")
.addAnnotatedClass(FullTimeEmployee.class)
.addAnnotatedClass(PartTimeEmployee.class)
.buildSessionFactory();
Session session = factory.getCurrentSession();
try {
session.beginTransaction();
// Retrieving FullTimeEmployee and PartTimeEmployee
List<FullTimeEmployee> fullTimeEmployees = session.createQuery("from FullTimeEmployee").getResultList();
List<PartTimeEmployee> partTimeEmployees = session.createQuery("from PartTimeEmployee").getResultList();
// Display the results
for (FullTimeEmployee employee : fullTimeEmployees) {
System.out.println("FullTimeEmployee: " + employee.getName() + ", Salary: " + employee.getSalary());
}
for (PartTimeEmployee employee : partTimeEmployees) {
System.out.println("PartTimeEmployee: " + employee.getName() + ", Hourly Rate: " + employee.getHourlyRate());
}
session.getTransaction().commit();
} finally {
factory.close();
}
}
}
Table per Class Strategy Hibernate-এ একটি ইনহেরিটেন্স স্ট্রাটেজি যা প্রতিটি ক্লাসের জন্য আলাদা টেবিল তৈরি করে। এটি ডাটাবেসে Inheritance সম্পর্কিত তথ্য ম্যানেজ করতে সহায়ক। যদিও এটি কিছু ডুপ্লিকেশন তৈরি করতে পারে এবং পারফরম্যান্সে কিছু প্রভাব ফেলতে পারে, তবে যখন ডেটাবেসের সম্পর্কগুলি আলাদা টেবিলের মধ্যে রাখতে হয় এবং জটিল JOIN
অপারেশন এড়িয়ে চলা দরকার, তখন এটি উপযুক্ত হয়।
এই স্ট্রাটেজির সাহায্যে আপনি ডেটা অরগানাইজ করতে পারবেন যেখানে প্রতিটি সাব ক্লাসের জন্য আলাদা টেবিল থাকবে এবং আপনাকে বিভিন্ন JOIN অপারেশন করার প্রয়োজন হবে না।
Read more